﻿using System;
using System.Linq;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

using Fuse8.DomainFramework.Domain;
using Fuse8.DomainFramework.Common;

namespace Fuse8.DomainFramework.ValidationService
{
    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class MetaDataEntityValidationService<T> : BaseEntityValidationService<T> where T : class, IEntityObject
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="entityObject"></param>
        /// <param name="actionType"></param>
        /// <returns></returns>
        public override ValidationResult Validate(T entityObject, ValidationActionType actionType)
        {
            //TypeDescriptor.AddProvider(new AssociatedMetadataTypeTypeDescriptionProvider(entityObject.GetType()), entityObject.GetType()); 

            Guard.ArgumentNotNull(entityObject, "entityObject");

            ValidationResult result = new ValidationResult { IsValid = true };

            var validationResults = TypeDescriptor.GetProperties(entityObject).Cast<PropertyDescriptor>()
                .SelectMany(p => p.Attributes.OfType<ValidationAttribute>(), (property, attribute) => new { property, attribute })
                .Where(p => !p.attribute.IsValid(p.property.GetValue(entityObject)))
                .Select(p =>
                    new ValidationResult
                    {
                        IsValid = false,
                        ValidationMessage = p.attribute.ErrorMessage
                    });

            if ((validationResults != null) && (validationResults.Count() > 0))
            {
                result = GlueResults(validationResults);
            }

            if (result.IsValid)
            {
                if (Successor != null)
                {
                    result = Successor.Validate(entityObject, actionType);
                }
            }

            return result;
        }
    }
}
